#pragma ident "$Id: ClockJump.hpp 2648 2011-06-09 08:01:41Z shjzhang $"

/**
 * @file ClockJump.hpp
 * General Solver.
 */

#ifndef GPSTK_ClockJump_HPP
#define GPSTK_ClockJump_HPP

//============================================================================
//
//  Revision
//
//  2019/08/13  
//  make a generic PPP solver for multiple-gnss data.  
//
//  2020/01/16 
//  modify the variable-class to replace the old ambiguity class  
//
//  shjzhang    
//
//============================================================================


#include "SolverBase.hpp"
#include "TypeID.hpp"
#include "ProcessingClass.hpp"
#include "EquationSystem.hpp"
#include "StochasticModel.hpp"
#include "SimpleKalmanFilter.hpp"
#include "SolverMWAR.hpp"


namespace gpstk
{

   ///////////////////////////////////////////////////////////////////
   // warning:
   // some solution realted data structures are defined in SolverBase
   // In the DIA method,
   // if the apriori variance is known, the Z-Test wil be used.
   ///////////////////////////////////////////////////////////////////
   class ClockJump : public SolverBase, public ProcessingClass
   {
   public:

      ClockJump()
          : firstTime(true), jumpThreshold(1.0E-3*C_MPS), sigma(5)
      {
          gpsCombTypeSet.clear();
          galCombTypeSet.clear();
          bdsCombTypeSet.clear();
          gloCombTypeSet.clear();

          usingGPS = true;
          usingGAL = false;
          usingBDS = false;
          usingGLO = false;

          gpsCombTypeSet.insert(TypeID::LC12);

          Init();
      }

         /** Returns a reference to a gnnsRinex object after solving
          *  the previously defined equation system.
          *
          * @param gData    Data object holding the data.
          */
      virtual gnssRinex& Process(gnssRinex& gData )
         noexcept(false);


      virtual void getEpochDiffData(gnssRinex& gData )
         noexcept(false);
      
      // get phase-clock-jump
      double getClockJump(gnssRinex& gRin);

      virtual ClockJump& addType(const TypeID& type, const SatID::SatelliteSystem& sys)
      {
          if(sys==SatelliteSystem::GPS)
          {
              usingGPS = true;
              gpsCombTypeSet.insert(type);
          }
          else if(sys==SatelliteSystem::Galileo)
          {
              usingGAL = true;
              galCombTypeSet.insert(type);
          }
          else if(sys==SatelliteSystem::BDS)
          {
              usingBDS = true;
              bdsCombTypeSet.insert(type);
          }
          else if(sys==SatelliteSystem::GLONASS)
          {
              usingGLO = true;
              gloCombTypeSet.insert(type);
          }
          return (*this);
      };


         /// Returns an index identifying this object.
      virtual void Init(void) ;

         /// Returns an index identifying this object.
      virtual int getIndex(void) const;

         /// Returns a string identifying this object.
      virtual std::string getClassName(void) const;

         /// Destructor.
      virtual ~ClockJump() {};

   private:

      bool firstTime;

      double jumpThreshold; 
      double sigma;

      bool usingGPS, usingGAL, usingBDS, usingGLO;

      TypeIDSet gpsCombTypeSet, galCombTypeSet, bdsCombTypeSet, gloCombTypeSet;

      satTypeValueMap stvDataPrev;

         /// Initial index assigned to this class.
      static int classIndex;

         /// Index belonging to this object.
      int index;

         /// Sets the index and increment classIndex.
      void setIndex(void)
      { index = classIndex++; };


   }; // End of class 'ClockJump'


      //@}

}  // End of namespace gpstk
#endif   // GPSTK_ClockJump_HPP
